package org.go.trigger;

import java.text.ParseException;
import java.util.TimeZone;

import org.go.domain.GoDomain;
import org.go.scheduler.ScheduleBuilder;

public class CronScheduleBuilder extends ScheduleBuilder {
	public static CronScheduleBuilder cronSchedule(String cronExpression) throws ParseException {
		CronExpression.validateExpression(cronExpression);
		return new CronScheduleBuilder(cronExpression);
	}

	private String cronExpression;

	private int misfireInstruction = CronTrigger.MISFIRE_INSTRUCTION_SMART_POLICY;

	private TimeZone tz;

	public CronScheduleBuilder(String cronExpression) {
		this.cronExpression = cronExpression;
	}

	/**
	 * Build the actual Trigger -- NOT intended to be invoked by end users,
	 * but will rather be invoked by a TriggerBuilder which this 
	 * ScheduleBuilder is given to.
	 * 
	 * @see TriggerBuilder#withSchedule(ScheduleBuilder)
	 */
	public Trigger build() {
		CronTrigger ct = new CronTrigger();
		try {
			ct.setCronExpression(cronExpression);
		} catch (ParseException e) {
			// all methods of construction ensure the expression is valid by this point...
			throw new RuntimeException("CronExpression '" + cronExpression + "' is invalid, which should not be possible, please report bug to Quartz developers.");
		}
		ct.setTimeZone(tz);
		ct.setMisfireInstruction(misfireInstruction);
		return ct;
	}

	public CronScheduleBuilder inTimeZone(TimeZone timeZone) {
		this.tz = timeZone;
		return this;
	}

	/**
	 * If the Trigger misfires, use the 
	 * {@link CronTrigger#MISFIRE_INSTRUCTION_DO_NOTHING} instruction.
	 * 
	 * @return the updated CronScheduleBuilder
	 * @see CronTrigger#MISFIRE_INSTRUCTION_DO_NOTHING
	 */
	public CronScheduleBuilder withMisfireHandlingInstructionDoNothing() {
		misfireInstruction = GoDomain.MISFIRE_INSTRUCTION_DO_NOTHING;
		return this;
	}

	/**
	* If the Trigger misfires, use the 
	* {@link CronTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW} instruction.
	* 
	* @return the updated CronScheduleBuilder
	* @see CronTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
	*/
	public CronScheduleBuilder withMisfireHandlingInstructionFireAndProceed() {
		misfireInstruction = GoDomain.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW;
		return this;
	}
}
